from rdflib import RDFS, RDF, Namespace
import collections

UCI_NS = Namespace("http://www.unifiedcloud.org/2009/2/26/uci.owl#")
AGENT_NS = Namespace("http://www.unifiedcloud.org/2009/3/9/agent_protocol#") 
ECP_NS = Namespace("http://www.enomaly.com/uci/2009/02/ecp#")



class InferenceEngine(object):
    def __init__(self, graph):
        self.graph = graph
            
    def get_instances_of(self, klass):
        """Returns all instances of specified klass using forward-chain inferencing"""
        insts = []
        open_classes = collections.deque([klass])
        closed_classes = set()
        while open_classes:
            c = open_classes.popleft()
            closed_classes.add(c)
    
            # Get instances of current class
            for s in self.graph.subjects(RDF.type, c):
                insts.append(s)
                
                
            # Get subclasses of current class
            for s in self.graph.subjects(RDFS.subClassOf, c):
                if s not in closed_classes:
                    open_classes.append(s)
        return insts
    
    
    def is_instance_of(self, uri, klass):     
        """Checks if given resource is instance of specified type"""   
        uri_klass = self.graph.value(uri, RDF.type)
        if uri_klass is None:
            return False
        
        if uri_klass == klass:
            return True
        
        open_classes = collections.deque([uri_klass])
        while open_classes:
            c = open_classes.popleft()
            
            for s in self.graph.objects(c, RDFS.subClassOf):
                if s == klass:
                    return True
                else:
                    open_classes.append(s)
                    
        return False    